﻿using CPPEI.Coolzon.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.UI.DataPartLib
{
    /// <summary>
    /// DataLabel.xaml 的交互逻辑
    /// </summary>
    [System.ComponentModel.DisplayName("数据标签")]
    [XPartIcon("pack://application:,,,/CPPEI.Coolzon.UI.DataPartLib;component/Images/PartIcons/数据标签.png")]
    public partial class DataLabel : DataItemPart
    {
        private ServiceProxy.DataServiceRef.DataResult _dataResult;
        private bool? _XIsShowShadow;
        private string _XShadowColor;
        private double? _XShadowDirection;
        private double? _XShadowDepth;
        private List<ConditionImage> _XConditionSuffix;
        private List<ConditionImage> _XConditionPrefix;
        private Thickness _XLabelMargin;
        private string _XTextFormat;
        private double _XFontSize;
        private TextAlignment _XTextAlign;
        private VerticalAlignment _XTextVAlign;
        private FontFamily _XFont;
        private System.Windows.FontWeight _XFontWeight;
        private bool _XIsEnableRefreshAnimation;
        private double _XRefreshAnimationDuration;
        private BrushEx _XRefreshBackground;

        #region XProperties
        /// <summary>
        /// 是否显示阴影
        /// </summary>
        [Category("Other")]
        [DisplayName("是否显示阴影")]
        [Description("IsShowShadow")]
        [Editor(typeof(UI.XProperty.Editors.XBooleanEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "IsShowShadow", "是否显示阴影")]
        public bool? XIsShowShadow
        {
            get
            {
                return _XIsShowShadow;
            }
            set
            {
                _XIsShowShadow = value;
                Refresh();
            }
        }
        /// <summary>
        /// 阴影颜色
        /// </summary>
        [Category("Other")]
        [DisplayName("阴影颜色#FF000000")]
        [Description("ShadowColor")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ShadowColor", "阴影颜色#FF000000")]
        public string XShadowColor
        {
            get
            {
                return _XShadowColor;
            }
            set
            {
                _XShadowColor = value;
                Refresh();
            }
        }
        /// <summary>
        /// 阴影方向
        /// </summary>
        [Category("Other")]
        [DisplayName("阴影方向0-360")]
        [Description("ShadowDirection")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ShadowDirection", "阴影方向0-360")]
        public Double? XShadowDirection
        {
            get
            {
                return _XShadowDirection;
            }
            set
            {
                _XShadowDirection = value;
                Refresh();
            }
        }
        /// <summary>
        /// 阴影深度
        /// </summary>
        [Category("Other")]
        [DisplayName("阴影深度")]
        [Description("ShadowDepth")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ShadowDepth", "阴影深度")]
        public Double? XShadowDepth
        {
            get
            {
                return _XShadowDepth;
            }
            set
            {
                _XShadowDepth = value;
                Refresh();
            }
        }

        [Category("Other")]
        [DisplayName("文本前缀")]
        [Description("ConditionSuffix")]
        [Editor(typeof(XProperty.Editors.XConditionImageEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ConditionSuffix", "文本前缀")]
        public List<ConditionImage> XConditionSuffix
        {
            get
            {
                return _XConditionSuffix;
            }
            set
            {
                _XConditionSuffix = value;
                Refresh();
            }
        }


        [Category("Other")]
        [DisplayName("文本后缀")]
        [Description("ConditionPrefix")]
        [Editor(typeof(XProperty.Editors.XConditionImageEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "ConditionPrefix", "文本后缀")]
        public List<ConditionImage> XConditionPrefix
        {
            get
            {
                return _XConditionPrefix;
            }
            set
            {
                _XConditionPrefix = value;
                Refresh();
            }
        }

        /// <summary>
        /// 文本边距
        /// </summary>
        [Category("Other")]
        [DisplayName("文本边距")]
        [Description("LabelMargin")]
        [Editor(typeof(UI.XProperty.Editors.XThicknessEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "LabelMargin", "文本边距")]
        public Thickness XLabelMargin
        {
            get
            {
                return _XLabelMargin;
            }
            set
            {
                _XLabelMargin = value;
                Refresh();
            }
        }

        /// <summary>
        /// 文本格式化{data.Value:0.00}
        /// </summary>
        [Category("Other")]
        [DisplayName("文本格式化")]
        [Description("TextFormat")]
        [Editor(typeof(UI.XProperty.Editors.XStringEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextFormat", "文本格式化")]
        public string XTextFormat
        {
            get
            {
                return _XTextFormat;
            }
            set
            {
                _XTextFormat = value;
                Refresh();
            }
        }

        /// <summary>
        /// 字体大小
        /// </summary>
        [Category("Other")]
        [DisplayName("字体大小")]
        [Description("FontSize")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FontSize", "字体大小")]
        public double XFontSize
        {
            get
            {
                return _XFontSize;
            }
            set
            {
                _XFontSize = value;
                Refresh();
            }
        }

        /// <summary>
        /// 字体问题
        /// </summary>
        [Category("Other")]
        [DisplayName("字体位置")]
        [Description("TextAlign")]
        [Editor(typeof(UI.XProperty.Editors.XTextAlignmentEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextAlign", "字体位置")]
        public TextAlignment XTextAlign
        {
            get
            {
                return _XTextAlign;
            }
            set
            {
                _XTextAlign = value;
                Refresh();
            }
        }

        /// <summary>
        /// 字体问题
        /// </summary>
        [Category("Other")]
        [DisplayName("字体垂直位置")]
        [Description("TextVAlign")]
        [Editor(typeof(UI.XProperty.Editors.XVerticalAlignmentEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "TextVAlign", "字体垂直位置")]
        public VerticalAlignment XTextVAlign
        {
            get
            {
                return _XTextVAlign;
            }
            set
            {
                _XTextVAlign = value;
                Refresh();
            }
        }

        /// <summary>
        /// 字体样式
        /// </summary>
        [Category("Other")]
        [DisplayName("字体")]
        [Description("Font")]
        [Editor(typeof(UI.XProperty.Editors.XFontFamilyEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "Font", "字体")]
        public FontFamily XFont
        {
            get
            {
                return _XFont;
            }
            set
            {
                _XFont = value;
                Refresh();
            }
        }
        [Category("Other")]
        [DisplayName("字体样式")]
        [Description("FontWeight")]
        [Editor(typeof(UI.XProperty.Editors.XFontWeightEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "FontWeight", "字体样式")]
        public FontWeight XFontWeight
        {
            get
            {
                return _XFontWeight;
            }
            set
            {
                _XFontWeight = value;
                Refresh();
            }
        }

        [Category("Other")]
        [DisplayName("是否更新数据时显示动画")]
        [Description("IsEnableRefreshAnimation")]
        [Editor(typeof(UI.XProperty.Editors.XBooleanEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "IsEnableRefreshAnimation", "是否更新数据时显示动画")]
        public bool XIsEnableRefreshAnimation
        {
            get
            {
                return _XIsEnableRefreshAnimation;
            }
            set
            {
                _XIsEnableRefreshAnimation = value;
                Refresh();
            }
        }
        
        [Category("Other")]
        [DisplayName("更新数据时显示动画的时间")]
        [Description("RefreshAnimationDuration")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "RefreshAnimationDuration", "更新数据时显示动画的时间")]
        public double XRefreshAnimationDuration
        {
            get
            {
                return _XRefreshAnimationDuration;
            }
            set
            {
                _XRefreshAnimationDuration = value;
                Refresh();
            }
        }
        
        [Category("Other")]
        [DisplayName("更新数据时显示背景的颜色")]
        [Description("RefreshBackground")]
        [Editor(typeof(UI.XProperty.Editors.XBrushEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Other, "RefreshBackground", "更新数据时显示背景的颜色")]
        public BrushEx XRefreshBackground
        {
            get
            {
                return _XRefreshBackground;
            }
            set
            {
                _XRefreshBackground = value;
                Refresh();
            }
        }
        #endregion


        #region Constructor

        public DataLabel()
        {
            XTextFormat = "{data.Value}";
            InitializeComponent();
        }
        protected override void OnInit(PartContext context)
        {
            base.OnInit(context);

            XIsEnableRefreshAnimation = false;
            XRefreshAnimationDuration = 1000;
            XRefreshBackground = new BrushEx(new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0xFF, 0x00)),"");
        }
        protected override void OnApplyXProperty()
        {
            base.OnApplyXProperty();

            if (gdLayout == null) return;

            if (XDataSource == null)
            {
                OriginalInit();
            }
        }
        private void OriginalInit()
        {
            ServiceProxy.DataServiceRef.DataResult dataResult = new ServiceProxy.DataServiceRef.DataResult();
            dataResult.DataSeries = new ServiceProxy.DataServiceRef.DataSeries[1];
            dataResult.DataSeries[0] = new ServiceProxy.DataServiceRef.DataSeries();
            dataResult.DataSeries[0].DataItems = new ServiceProxy.DataServiceRef.DataItem[1];
            dataResult.DataSeries[0].DataItems[0] = new ServiceProxy.DataServiceRef.DataItem() { Name = "北京", Value = "100.90" };
            _dataResult = dataResult;

            OnDataItemBinding(dataResult.DataSeries[0].DataItems[0]);
        }
        protected override void OnActive(PartContext context)
        {
            base.OnActive(context);
        }
        protected override void OnDataBinding(ServiceProxy.DataServiceRef.DataResult dataResult)
        {
            _dataResult = dataResult;
            base.OnDataBinding(dataResult);
        }
        protected override void OnDataItemBinding(ServiceProxy.DataServiceRef.DataItem dataItem)
        {
            if (!string.IsNullOrEmpty(XTextFormat))
            {
                gdLayout.Children.Clear();

                StackPanel sp = null;
                if ((XConditionPrefix != null && XConditionPrefix.Any()) || (XConditionSuffix != null && XConditionSuffix.Any()))
                {
                    sp = new StackPanel();
                    sp.Orientation = Orientation.Horizontal;
                    gdLayout.Children.Add(sp);
                }
                if (XConditionPrefix != null && XConditionPrefix.Any())
                {
                    ConditionControl prefix = null;
                    foreach (ConditionImage imagePrefix in XConditionPrefix)
                    {
                        prefix = ConditionControlFactory.Create(this, _dataResult, _dataResult.DataSeries[0], dataItem);
                        prefix.SetProperty("Condition", imagePrefix.Condition.Trim());
                        prefix.SetProperty("ImageSource", imagePrefix.ImageSource);
                        prefix.ValidateCondition();

                        if (sp == null)
                        {
                            gdLayout.Children.Add(prefix);
                        }
                        else
                        {
                            sp.Children.Add(prefix);
                        }
                    }
                }

                TextBlock tbText = new TextBlock();
                //tbText.RegisterName("tbText", gdLayout);
                InitControl(tbText);
                tbText.Text = FormartText(dataItem);
                tbText.Effect = GetDropShadowEffect();
                if (sp == null)
                {
                    gdLayout.Children.Add(tbText);
                }
                else
                {
                    sp.Children.Add(tbText);
                }


                if (XConditionSuffix != null && XConditionSuffix.Any())
                {
                    ConditionControl suffix = null;
                    foreach (ConditionImage imageSuffix in XConditionSuffix)
                    {
                        suffix = ConditionControlFactory.Create(this, _dataResult, _dataResult.DataSeries[0], dataItem);
                        suffix.SetProperty("Condition", imageSuffix.Condition.Trim());
                        suffix.SetProperty("ImageSource", imageSuffix.ImageSource);
                        suffix.ValidateCondition();

                        if (sp == null)
                        {
                            gdLayout.Children.Add(suffix);
                        }
                        else
                        {
                            sp.Children.Add(suffix);
                        }
                    }
                }

                //if (XIsEnableRefreshAnimation)
                //{
                //    //暂时取消动画
                //    RefreshAnimation1(tbText);
                //}
            }
        }

        /// <summary>
        /// 刷新数据时动画
        /// </summary>
        private void RefreshAnimation()
        {
            if (gdLayout.Background == null)
            {
                gdLayout.Background = new SolidColorBrush();
            }
            BrushEx oldBackground = XBackground;
            if (XBackground == null)
            {
                oldBackground = new BrushEx(gdLayout.Background, "");
            }
            ColorAnimation refreshAnimation = new ColorAnimation();
            refreshAnimation.From = ((SolidColorBrush)XRefreshBackground.Brush).Color;
            refreshAnimation.To = ((SolidColorBrush)XRefreshBackground.Brush).Color;
            refreshAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(XRefreshAnimationDuration));
            refreshAnimation.Completed += (o, e) =>
            {
                gdLayout.Background.BeginAnimation(SolidColorBrush.ColorProperty, null);
                gdLayout.Background = oldBackground.Brush;
            };
            gdLayout.Background.BeginAnimation(SolidColorBrush.ColorProperty, refreshAnimation);
        }
        private void RefreshAnimation1(TextBlock tbText)
        {
            if (tbText.Foreground == null)
            {
                return;
            }
            tbText.Visibility = Visibility.Collapsed;

            ColorAnimation refreshAnimation = new ColorAnimation();
            refreshAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(XRefreshAnimationDuration));
            refreshAnimation.Completed += (o, e) =>
            {
                tbText.Visibility = Visibility.Visible;
            };
            tbText.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, refreshAnimation);
        }

        private string FormartText(ServiceProxy.DataServiceRef.DataItem dataItem)
        {
            Regex r = new Regex(@"{[^{}]*}");
            MatchCollection matchs = r.Matches(XTextFormat);
            string newText = XTextFormat;
            foreach (Match match in matchs)
            {
                string matchResult = match.Value.Trim(new char[] { '{', '}' });
                if (matchResult.StartsWith("data"))
                {
                    string[] values = matchResult.Replace("data.", "").Split(new string[] { ":" }, StringSplitOptions.None);
                    PropertyInfo[] propertyInfos = dataItem.GetType().GetProperties();
                    for (int i = 0; i < propertyInfos.Length; i++)
                    {
                        string name = propertyInfos[i].Name.ToUpper();
                        if (values[0].ToUpper().Equals(name))
                        {
                            object obj = propertyInfos[i].GetValue(dataItem);

                            if (values.Length > 1)
                            {
                                double res = default(double);
                                if (double.TryParse(obj.ToString(), out res))
                                {
                                    newText = newText.Replace(match.Value, res.ToString(values[1]));
                                    break;
                                }
                            }
                            newText = newText.Replace(match.Value, obj.ToString());
                            break;
                        }
                    }
                }
                else if (matchResult.StartsWith("@"))
                {
                    string value = matchResult.TrimStart(new char[] { '@' });
                    Metadata.Parameter parameter = this.GetParameter(value);
                    if (parameter != null)
                    {
                        newText = newText.Replace(match.Value, value);
                    }
                }
                else if (matchResult.StartsWith("condition"))
                {
                    string expression = matchResult.Split(new string[] { "=>" }, StringSplitOptions.RemoveEmptyEntries)[1];
                    newText = newText.Replace(match.Value, 
                        (string)this.PartContext.ScriptEngine.RunExpression(expression.Replace("data.value", dataItem.Value)));
                }
            }
            return newText;
        }

        /// <summary>
        /// 初始化控件属性
        /// </summary>
        private void InitControl(TextBlock tbText)
        {
            if (XFontSize != 0)
            {
                tbText.FontSize = XFontSize;
            }
            tbText.TextAlignment = XTextAlign;
            tbText.VerticalAlignment = XTextVAlign;
            if (XFont != null)
            {
                tbText.FontFamily = XFont;
            }
                tbText.FontWeight = XFontWeight;
            if (XForeground != null)
            {
                tbText.Foreground = XForeground.Brush;
            }
                tbText.Margin = XLabelMargin;
            }

        #endregion

        /// <summary>
        /// 获取阴影对象
        /// </summary>
        /// <returns></returns>
        protected DropShadowEffect GetDropShadowEffect()
        {
            if (XIsShowShadow != null && XIsShowShadow.Value)
            {
                DropShadowEffect effect = new DropShadowEffect();
                if (!string.IsNullOrWhiteSpace(XShadowColor))
                {
                    effect.Color = (Color)ColorConverter.ConvertFromString(XShadowColor);
                }
                if (XShadowDirection != null)
                {
                    effect.Direction = XShadowDirection.Value;
                }
                if (XShadowDepth != null)
                {
                    effect.ShadowDepth = XShadowDepth.Value;
                }
                return effect;
            }
            else
                return null;

        }
    }
}
